package lightswitch.server.code.util;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringHelper {

	public String str;

	public StringHelper() {

	}

	public StringHelper(String st) {
		str = st;
	}

	public static String GetStringInParenthesis(String str) {
		int level = 0;

		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) == '(') {
				level++;
			} else {
				if (str.charAt(i) == ')') {
					level--;
				}
			}
			if (level == 0) {
				return str.substring(1, i);
			}
		}
		return "";
	}

	public static String GetStringInSingleFlash(String str) {

		Pattern p = Pattern.compile("('[^']+')");
		Matcher m = p.matcher(str);
		if (m.find()) {
		
			return m.group(1);
		}
		return null;

	}

	public static String GetStringInHypotenuse(String str) {

		Pattern p = Pattern.compile("(`[^`]+`)");
		Matcher m = p.matcher(str);
		if (m.find()) {
		
			return m.group(1);
		}
		return null;

	}

	public static boolean CheckParenthesis(String str) {
		int level = 0;
		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) == '(')
				level++;
			else {
				if (str.charAt(i) == ')') {
					level--;
				}
			}
		}
		if (level == 0)
			return true;
		return false;
	}

	public static String NormalizeString(String str) {
		if (str.equals(""))
			return "";

		str = str.toLowerCase();
		Pattern p = Pattern.compile("(\\s+)");
		Matcher m = p.matcher(str);

		StringBuffer result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, " ");
		}
		m.appendTail(result);
		String temp = result.toString();
		if (str.equals(" "))
			return "";

		p = Pattern.compile("(\\s\\.\\s)|(\\s\\.)|(\\.\\s)");
		m = p.matcher(temp);

		StringBuffer result1 = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result1, ".");
		}
		m.appendTail(result1);
		temp = result1.toString();

		

		// p = Pattern.compile("(\\s\\)\\s)|(\\s\\))|(\\))|(\\)\\s)");
		p = Pattern.compile("(\\s\\)\\s)|(\\s\\))|(\\)\\s)|(\\))");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, ") ");

		}
		m.appendTail(result);
		temp = result.toString();

		p = Pattern.compile("(\\s\\(\\s)|(\\(\\s)|(\\s\\()|(\\()");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, " (");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("(\\(\\s\\()");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, "((");

		}
		m.appendTail(result);
		temp = result.toString();

		p = Pattern.compile("(\\)\\s\\))");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, "))");

		}
		m.appendTail(result);
		temp = result.toString();

		
		
		p = Pattern.compile("(\\s,\\s)|(\\s,)|(,)");
		m = p.matcher(temp);
		StringBuffer result2 = new StringBuffer();
		// result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result2, ", ");

			// result.append(" ");
		}
		m.appendTail(result2);

		temp = result2.toString();
		
		

		String[] symboy = { "\\+", "-", "/", "<", ">", "> =", "< =", "=", "\\*" };
		String[] replaceSymboy = { "+", "-", "/", "<", ">", ">=", "<=", "=",
				"*" };
		for (int i = 0; i < symboy.length; i++) {
			String t = "(\\s" + symboy[i] + "\\s)|(\\s" + symboy[i] + ")|("
					+ symboy[i] + "\\s)|(" + symboy[i] + ")";
			p = Pattern.compile(t);
			m = p.matcher(temp);

			result = new StringBuffer();
			while (m.find()) {

				m.appendReplacement(result, " " + replaceSymboy[i] + " ");

			}
			m.appendTail(result);
			temp = result.toString();
		}

	
		// >=

		p = Pattern.compile("(>\\s\\=)");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, ">=");

		}
		m.appendTail(result);
		temp = result.toString();

		p = Pattern.compile("(<\\s=)");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, "<=");

		}
		m.appendTail(result);
		temp = result.toString();

		p = Pattern.compile("(<\\s>)");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, "<>");

		}
		m.appendTail(result);
		temp = result.toString();

		p = Pattern.compile("(\\!\\s=)");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, "<>");

		}
		m.appendTail(result);
		temp = result.toString();

		p = Pattern.compile("((\\s-\\s)([0-9]+))");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result, "-" + m.group(3));

		}
		m.appendTail(result);
		temp = result.toString();

		
		
		p = Pattern.compile("group by");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"groupby");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("order by");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"orderby");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("not in");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"notin");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("not between");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"notbetween");

		}
		m.appendTail(result);
		temp = result.toString();
		
		
		
		p = Pattern.compile("not like");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"notlike");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("not exist");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"notexist");

		}
		m.appendTail(result);
		temp = result.toString();
		
		
		
		p = Pattern.compile("<> all");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"<>all");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("> all");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,">all");

		}
		m.appendTail(result);
		temp = result.toString();
		
		
		p = Pattern.compile(">= all");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,">=all");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("< all");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"<all");

		}
		m.appendTail(result);
		temp = result.toString();
		
		
		p = Pattern.compile("<= all");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"<=all");

		}
		m.appendTail(result);
		temp = result.toString();
		
		
		p = Pattern.compile("= all");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"=all");

		}
		m.appendTail(result);
		temp = result.toString();
		
		
		p = Pattern.compile("is null");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"= null");

		}
		m.appendTail(result);
		temp = result.toString();
		
		p = Pattern.compile("is not null");
		m = p.matcher(temp);

		result = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result,"<> null");

		}
		m.appendTail(result);
		temp = result.toString();
		
		// ////////////////////////
		// ////////////////////////
		// ////////////////////////


		p = Pattern.compile("(\\s+)");
		 m = p.matcher(temp);

		StringBuffer result5 = new StringBuffer();
		while (m.find()) {

			m.appendReplacement(result5, " ");
		}
		m.appendTail(result5);
		temp=result5.toString();


		
		
		if (temp.charAt(0) == ' ')
			temp = temp.substring(1);

		if (temp.charAt(temp.length() - 1) == ' ') {
			temp = temp.substring(0, temp.length() - 1);
		}

		return temp;

	}

	public static List<String> SplitStringInEqualLevel(String str) {
		str = NormalizeString(str);
		List<String> result = new ArrayList<String>();

		String temp = "";
		String tempToPush = "";
		String[] strSplit = str.split("(\\s)");

		List<String> strToCheckPar = new ArrayList<String>();
		// lay trong nhay kep
		for (int i = 0; i < strSplit.length; i++) {
			temp = "";
			if (strSplit[i].charAt(0) == 39) {
				int j = i;
				for (j = i; j < strSplit.length; j++) {
					temp += strSplit[j] + " ";
				}
				temp = StringHelper.NormalizeString(temp);

				tempToPush = StringHelper.GetStringInSingleFlash(temp);
				i += tempToPush.split(" ").length - 1;
				//xxx
				for (int k = tempToPush.split(" ")[tempToPush.split(" ").length-1].length(); k < strSplit[i].length(); k++) {
					tempToPush += temp.charAt(k);
				}
				
				// i=j-1;
				strToCheckPar.add(tempToPush);
			} else {
				if (strSplit[i].charAt(0) == '`') {
					int j = i;
					for (j = i; j < strSplit.length; j++) {
						temp += strSplit[j] + " ";
					}
					temp = StringHelper.NormalizeString(temp);

					tempToPush = StringHelper.GetStringInHypotenuse(temp);
					i += tempToPush.split(" ").length - 1;
					// i=j-1;
					//xxx
					for (int k = tempToPush.split(" ")[tempToPush.split(" ").length-1].length(); k < strSplit[i].length(); k++) {
						tempToPush += temp.charAt(k);
					}
					
					strToCheckPar.add(tempToPush);
				} else {
					strToCheckPar.add(strSplit[i]);
				}
			}

		}
			for (int i = 0; i < strToCheckPar.size(); i++) {
			temp = "";
			if (strToCheckPar.get(i).charAt(0) == '(') {
				int j = i;
				for (j = i; j < strToCheckPar.size(); j++) {
					temp += strToCheckPar.get(j) + " ";
				}
				temp = StringHelper.NormalizeString(temp);

				tempToPush = StringHelper.GetStringInParenthesis(temp);
				i += tempToPush.split(" ").length - 1;
				// i=j-1;
				result.add(tempToPush);
			} else {
				result.add(strToCheckPar.get(i));
			}

		}

		return result;
	}
	
	public static List<String> SplitStringInEqualLevelKeepingToken(String str) {
		str = NormalizeString(str);
		List<String> result = new ArrayList<String>();

		String temp = "";
		String tempToPush = "";
		String[] strSplit = str.split("(\\s)");

		List<String> strToCheckPar = new ArrayList<String>();
		// lay trong nhay kep
		for (int i = 0; i < strSplit.length; i++) {
			temp = "";
			if (strSplit[i].charAt(0) == 39) {
				int j = i;
				for (j = i; j < strSplit.length; j++) {
					temp += strSplit[j] + " ";
				}
				temp = StringHelper.NormalizeString(temp);

				tempToPush = StringHelper.GetStringInSingleFlash(temp);
				i += tempToPush.split(" ").length - 1;
				//xxx
				for (int k = tempToPush.split(" ")[tempToPush.split(" ").length-1].length(); k < strSplit[i].length(); k++) {
					tempToPush += temp.charAt(k);
				}
				
				 //xxx
				strToCheckPar.add(tempToPush);
			} else {
				if (strSplit[i].charAt(0) == '`') {
					int j = i;
					for (j = i; j < strSplit.length; j++) {
						temp += strSplit[j] + " ";
					}
					temp = StringHelper.NormalizeString(temp);

					tempToPush = "`"+ StringHelper.GetStringInHypotenuse(temp)+"`";
					i += tempToPush.split(" ").length - 1+2;
					// i=j-1;
					//XXX
					for (int k = tempToPush.split(" ")[tempToPush.split(" ").length-1].length(); k < strSplit[i].length(); k++) {
						tempToPush += temp.charAt(k);
					}
					
					
					strToCheckPar.add(tempToPush);
				} else {
					strToCheckPar.add(strSplit[i]);
				}
			}

		}
			for (int i = 0; i < strToCheckPar.size(); i++) {
			temp = "";
			if (strToCheckPar.get(i).charAt(0) == '(') {
				int j = i;
				for (j = i; j < strToCheckPar.size(); j++) {
					temp += strToCheckPar.get(j) + " ";
				}
				temp = StringHelper.NormalizeString(temp);

				tempToPush = "("+ StringHelper.GetStringInParenthesis(temp)+")";
				i += tempToPush.split(" ").length - 1;
				// i=j-1;
				result.add(tempToPush);
			} else {
				result.add(strToCheckPar.get(i));
			}

		}

		return result;
	}
	
}
